home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include <values.h>
-
- void InitFFT(int n);
- void FFT(double far *Input,double far *OutputRe,double far *OutputIm);
- void CleanUpFFT(void);
- void IFFT(double far *InputRe,double far *InputIm,double far *Output);
-
-
- static double *ReplaceXData;
- static double *ReplaceYData;
- static double *SinTwids;
- static int *UnscrambledIndex;
- static int N,N_DIV_4,LOG2Ndiv2;
-
- void InitFFT(int n)
- {
- int i,j;
- N=n;
- N_DIV_4=N/4;
- LOG2Ndiv2=(int(log(N)/log(2))+1)>>1; //Juist afronden en snel
-
- ReplaceXData=new double[N];
- ReplaceYData=new double[N];
- SinTwids=new double[N+N/4];
- UnscrambledIndex=new int[N];
-
- for (i=0;i<N+N_DIV_4;i++) SinTwids[i]=sin(i*(2*M_PI/N));
- for (i=0;i<N;i++)
- {
- UnscrambledIndex[i]=0;
- for (j=0;j<LOG2Ndiv2;j++)
- UnscrambledIndex[i]|=((i>>((LOG2Ndiv2-1-j)<<1))&0x3)<<(j<<1);
- }
-
- }
-
- void CleanUpFFT(void)
- {
- delete [] ReplaceXData;
- delete [] ReplaceYData;
- delete [] SinTwids;
- delete [] UnscrambledIndex;
- }
-
- void FFT(double far *Input,double far *OutputRe,double far *OutputIm)
- {
- int BFlys=N_DIV_4,BFlysBy3=(N*3)/4;
- int Groups=1,GroupsBy2=2,GroupsBy3=3;
- int Stage,Group,BFly;
- int i;
-
- double *XA,*XB,*XC,*XD;
- double *YA,*YB,*YC,*YD;
- double xa,xb,xc,xd;
- double ya,yb,yc,yd;
- double *Cb,*Cc,*Cd;
- double *Sb,*Sc,*Sd;
-
- for (i=0;i<N;i++) ReplaceXData[i]=Input[i];
- for (i=0;i<N;i++) ReplaceYData[i]=0;
-
- for (Stage=LOG2Ndiv2;Stage;Stage--)
- {
- XA=ReplaceXData;
- XB=XA+BFlys;
- XC=XB+BFlys;
- XD=XC+BFlys;
- YA=ReplaceYData;
- YB=YA+BFlys;
- YC=YB+BFlys;
- YD=YC+BFlys;
- for(Group=Groups;Group;Group--)
- {
- Cb=Cc=Cd=SinTwids+N_DIV_4;
- Sb=Sc=Sd=SinTwids;
- for(BFly=BFlys;BFly;BFly--)
- {
- xa=*XA; xb=*XB; xc=*XC; xd=*XD;
- ya=*YA; yb=*YB; yc=*YC; yd=*YD;
-
- *XA++=xa+xb+xc+xd;
- *YA++=ya+yb+yc+yd;
- *XB++=(xa+yb-xc-yd)*(*Cb)+(ya-xb-yc+xd)*(*Sb);
- *YB++=(ya-xb-yc+xd)*(*Cb)-(xa+yb-xc-yd)*(*Sb);
- *XC++=(xa-xb+xc-xd)*(*Cc)+(ya-yb+yc-yd)*(*Sc);
- *YC++=(ya-yb+yc-yd)*(*Cc)-(xa-xb+xc-xd)*(*Sc);
- *XD++=(xa-yb-xc+yd)*(*Cd)+(ya+xb-yc-xd)*(*Sd);
- *YD++=(ya+xb-yc-xd)*(*Cd)-(xa-yb-xc+yd)*(*Sd);
-
- Cb+=Groups;
- Cc+=GroupsBy2;
- Cd+=GroupsBy3;
-
- Sb+=Groups;
- Sc+=GroupsBy2;
- Sd+=GroupsBy3;
- } /* ButterFly */
-
- XA+=BFlysBy3;
- XB+=BFlysBy3;
- XC+=BFlysBy3;
- XD+=BFlysBy3;
-
- YA+=BFlysBy3;
- YB+=BFlysBy3;
- YC+=BFlysBy3;
- YD+=BFlysBy3;
-
- } /* Group */
-
- Groups<<=2;
- GroupsBy2<<=2;
- GroupsBy3<<=2;
- BFlys>>=2;
- BFlysBy3>>=2;
- } /* Stage */
-
- /* Unscramble */
- for (i=0;i<N;i++) OutputRe[i]=ReplaceXData[UnscrambledIndex[i]];
- for (i=0;i<N;i++) OutputIm[i]=ReplaceYData[UnscrambledIndex[i]];
- } /* FFT */
-
-
-
- void IFFT(double far *InputRe,double far *InputIm,double far *Output)
- {
- int BFlys=N_DIV_4,BFlysBy3=(N*3)/4;
- int Groups=1,GroupsBy2=2,GroupsBy3=3;
- int Stage,Group,BFly;
- int i;
-
- double *XA,*XB,*XC,*XD;
- double *YA,*YB,*YC,*YD;
- double xa,xb,xc,xd;
- double ya,yb,yc,yd;
- double *Cb,*Cc,*Cd;
- double *Sb,*Sc,*Sd;
-
- // FFT(complex toegevoegde)=N*IFFT
- for (i=0;i<N;i++) ReplaceXData[i]=InputRe[i];
- for (i=0;i<N;i++) ReplaceYData[i]=-InputIm[i];
-
- for (Stage=LOG2Ndiv2;Stage;Stage--)
- {
- XA=ReplaceXData;
- XB=XA+BFlys;
- XC=XB+BFlys;
- XD=XC+BFlys;
- YA=ReplaceYData;
- YB=YA+BFlys;
- YC=YB+BFlys;
- YD=YC+BFlys;
- for(Group=Groups;Group;Group--)
- {
- Cb=Cc=Cd=SinTwids+N_DIV_4;
- Sb=Sc=Sd=SinTwids;
- for(BFly=BFlys;BFly;BFly--)
- {
- xa=*XA; xb=*XB; xc=*XC; xd=*XD;
- ya=*YA; yb=*YB; yc=*YC; yd=*YD;
-
- *XA++=xa+xb+xc+xd;
- *YA++=ya+yb+yc+yd;
- *XB++=(xa+yb-xc-yd)*(*Cb)+(ya-xb-yc+xd)*(*Sb);
- *YB++=(ya-xb-yc+xd)*(*Cb)-(xa+yb-xc-yd)*(*Sb);
- *XC++=(xa-xb+xc-xd)*(*Cc)+(ya-yb+yc-yd)*(*Sc);
- *YC++=(ya-yb+yc-yd)*(*Cc)-(xa-xb+xc-xd)*(*Sc);
- *XD++=(xa-yb-xc+yd)*(*Cd)+(ya+xb-yc-xd)*(*Sd);
- *YD++=(ya+xb-yc-xd)*(*Cd)-(xa-yb-xc+yd)*(*Sd);
-
- Cb+=Groups;
- Cc+=GroupsBy2;
- Cd+=GroupsBy3;
-
- Sb+=Groups;
- Sc+=GroupsBy2;
- Sd+=GroupsBy3;
- } /* ButterFly */
-
- XA+=BFlysBy3;
- XB+=BFlysBy3;
- XC+=BFlysBy3;
- XD+=BFlysBy3;
-
- YA+=BFlysBy3;
- YB+=BFlysBy3;
- YC+=BFlysBy3;
- YD+=BFlysBy3;
-
- } /* Group */
-
- Groups<<=2;
- GroupsBy2<<=2;
- GroupsBy3<<=2;
- BFlys>>=2;
- BFlysBy3>>=2;
- } /* Stage */
-
- /* Unscramble */
- for (i=0;i<N;i++) Output[i]=ReplaceXData[UnscrambledIndex[i]]/N;
- } /* FFT */
-
-